package com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.lesson.sample.server.handle;

import java.io.File;
import java.io.IOException;
import java.nio.channels.SocketChannel;
import java.util.concurrent.Executor;

import com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.lesson.sample.foo.Foo;
import com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.lesson.sample.foo.handle.ConnectorCloseChain;
import com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.lesson.sample.foo.handle.ConnectorStringPacketChain;
import com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.lesson.sample.foo.handle.DefaultNonConnectorStringPacketChain;
import com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.lesson.sample.foo.handle.DefaultPrintConnectorCloseChain;
import com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.library.clink.box.StringReceivePacket;
import com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.library.clink.core.Connector;
import com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.library.clink.core.Packet;
import com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.library.clink.core.ReceivePacket;
import com.jdk.demo.nio.bilibili.Maodun.net.qiujuer2.library.clink.utils.CloseUtils;

public class ClientHandler extends Connector {
	private final File cachePath;
    private final String clientInfo;
    private final Executor deliveryPool;
    private final ConnectorCloseChain closeChain = new DefaultPrintConnectorCloseChain();
    private final ConnectorStringPacketChain stringPacketChain = new DefaultNonConnectorStringPacketChain();

    public ClientHandler(SocketChannel socketChannel, File cachePath, Executor deliveryPool) throws IOException {
        this.clientInfo = socketChannel.getRemoteAddress().toString();
        this.cachePath = cachePath;
        this.deliveryPool = deliveryPool;

        System.out.println("新客户端连接：" + clientInfo);

        setup(socketChannel);
    }

    public String getClientInfo() {
		return clientInfo;
	}

	public void exit() {
        CloseUtils.close(this);
        closeChain.handle(this, this);
    }

    @Override
    public void onChannelClosed(SocketChannel channel) {
    	super.onChannelClosed(channel);
    	closeChain.handle(this, this);
    }

	@Override
	protected File createNewReceiveFile() {
		return Foo.createRandomTemp(cachePath);
	}

    @Override
	protected void onReceivedPacket(ReceivePacket packet) {
        super.onReceivedPacket(packet);
        switch (packet.type()) {
			case Packet.TYPE_MEMORY_STRING: {
				deliveryStringPacket((StringReceivePacket)packet);
				break;
			}
			default: {
				System.out.println("New PAcket:" + packet.type() + "-" + packet.length());
			}
		}
    }

    private void deliveryStringPacket(StringReceivePacket packet) {
    	deliveryPool.execute(() -> stringPacketChain.handle(this, packet));
	}

	public ConnectorStringPacketChain getStringPacketChain() {
		return stringPacketChain;
	}

	public ConnectorCloseChain getCloseChain() {
		return closeChain;
	}

}
